package btb.ui;

import de.matthiasmann.twl.DialogLayout;
import de.matthiasmann.twl.EditField;
import de.matthiasmann.twl.Event;
import de.matthiasmann.twl.ResizableFrame;
import de.matthiasmann.twl.ScrollPane;
import de.matthiasmann.twl.TextArea;
import de.matthiasmann.twl.textarea.HTMLTextAreaModel;
import org.lwjgl.Sys;

import btb.engine.CTaskMessenger;
import btb.net.CNetwork.NChatMessage;
import btb.net.CNetworkEvent;
//import test.TestUtils;

public class CChatFrame extends ResizableFrame
{
	private final StringBuilder sb;
	private final HTMLTextAreaModel textAreaModel;
	private final TextArea textArea;
	private final EditField editField;
	private final ScrollPane scrollPane;
	
	private int curColor;
	private String username;

	public CChatFrame(String _username)
	{
		setTitle("Chat");
		this.username = _username;

	    this.sb = new StringBuilder();
	    this.textAreaModel = new HTMLTextAreaModel();
	    this.textArea = new TextArea(textAreaModel);
	    this.editField = new EditField();

	    editField.addCallback(new EditField.Callback()
	    {
	    	public void callback(int key)
	    	{
	        	if(key == Event.KEY_RETURN)
	        	{
	        		String str = editField.getText();
	        		attemptChatMsgSend(str);
	        		
	            	// cycle through 3 different colors/font styles
	                appendRow("color" + curColor, str, "");
	                curColor = (curColor + 1) % 3;
	            	editField.setText("");
	        	}
	    	}
	    });

	    textArea.addCallback(new TextArea.Callback()
	    {
	    	public void handleLinkClicked(String href)
	    	{
	    		Sys.openURL(href);
	    	}
	    });

	    scrollPane = new ScrollPane(textArea);
	    scrollPane.setFixed(ScrollPane.Fixed.HORIZONTAL);

	    DialogLayout l = new DialogLayout();
	    l.setTheme("content");
	    l.setHorizontalGroup(l.createParallelGroup(scrollPane, editField));
	    l.setVerticalGroup(l.createSequentialGroup(scrollPane, editField));

	    add(l);

	    appendRow("default", "Welcome to the chat room. Type your messages below :)", "SERVER");
	}

	private void attemptChatMsgSend(String _text)
	{
		NChatMessage msg = new NChatMessage();
		msg.channelName = ((AGuiObject) this.getParent()).callingTask.channelName;
		msg.senderName = ((AGuiObject) this.getParent()).callingTask.username;
		msg.text = _text;
		
		CNetworkEvent netevent = new CNetworkEvent(((AGuiObject)this.getParent()).callingTask, CNetworkEvent.CNE_CHAT_MESSAGE, msg);
		
		((AGuiObject) this.getParent()).callingTask.getMailbox().push(CTaskMessenger.TASK_CCLIENT, netevent);
	}
	
	public void receiveChatMessage(NChatMessage msg)
	{
		 appendRow("color" + curColor, msg.text, msg.senderName);
		 curColor = (curColor + 1) % 3;
	}
	
	public void receiveChatServerMessage(String _text)
	{
		appendRow("color" + curColor, _text, "SERVER");
		curColor = (curColor + 1) % 3;
	}
	
	private void appendRow(String _font, String _text, String _sender)
	{
		sb.append("<div style=\"word-wrap: break-word; font-family: ").append(_font).append("; \">");
		
		String sender;
		if(_sender.equals(""))
			sender = this.username;
		else
			sender = _sender;
		
		sb.append("[" + sender + "]: ");
		
	    // not efficient but simple
	    for(int i=0, l=_text.length(); i<l; i++)
	    {
	    	char ch = _text.charAt(i);
	        switch(ch)
	        {
	        case '<': sb.append("&lt;"); break;
	        case '>': sb.append("&gt;"); break;
	        case '&': sb.append("&amp;"); break;
	        case '"': sb.append("&quot;"); break;
	        case ':':
	        	if(_text.startsWith(":)", i))
	        	{
	        		sb.append("<img src=\"smiley\" alt=\":)\"/>");
	                i += 1; // skip one less because of i++ in the for loop
	                break;
	        	}
	            sb.append(ch);
	            break;
	        case 'h':
	        	if(_text.startsWith("http://", i)) 
	            {
	        		int end = i + 7;
	                while(end < l && isURLChar(_text.charAt(end)))
	                {
	                	end++;
	                }
	                String href = _text.substring(i, end);
	                sb.append("<a style=\"font: link\" href=\"").append(href)
	                	.append("\" >").append(href)
	                    .append("</a>");
	                i = end - 1; // skip one less because of i++ in the for loop
	                break;
	            }
	        	// fall through:
	        default:
	        	sb.append(ch);
	        }
	    }
	    sb.append("</div>");

	    boolean isAtEnd = scrollPane.getMaxScrollPosY() == scrollPane.getScrollPositionY();

	    textAreaModel.setHtml(sb.toString());

	    if(isAtEnd)
	    {
	    	scrollPane.validateLayout();
	    	scrollPane.setScrollPositionY(scrollPane.getMaxScrollPosY());
	    }
	}

	public String getUsername(){return username;}
	public void setUsername(String _username){this.username = _username;}
	
	private boolean isURLChar(char ch)
	{
		return (ch == '.') || (ch == '/') || (ch == '%') ||
			(ch >= '0' && ch <= '9') ||
			(ch >= 'a' && ch <= 'z') ||
			(ch >= 'A' && ch <= 'Z');
	}	
}